/**
 * common
 */

layui.define(function (exports) {
    var $ = layui.$, setter = layui.setter, admin = layui.admin, table = layui.table, form = layui.form,
        upload = layui.upload

    //公共业务的逻辑处理可以写在此处，切换任何页面都会执行
    //……
    table.set({
        // headers: { //通过 request 头传递
        //     access_token: layui.data(setter.tableName).access_token
        // }
        // ,
        where: { //通过参数传递
            access_token: layui.data(setter.tableName).access_token
        }
    });


    //退出
    admin.events.logout = function () {
        //执行退出接口
        admin.req({
            //url: './res/json/user/logout.js'
            url: window.globalConfig.url_login + "/1", type: 'delete', data: {}, done: function (res) { //这里要说明一下：done 是只有 response 的 code 正常才会执行。而 succese 则是只要 http 为 200 就会执行
                //清空本地记录的 token，并跳转到登入页
                admin.exit();
            }
        });
    };

    /**
     * 初始化编辑器
     * @param selector
     * @returns {*}
     */
    var editor = (selector = "editor") => {
        tinymce.remove(`#${selector}`)
        return tinymce.init({
            selector: `#${selector}`,
            language: 'zh_CN',
            plugins: 'codeeditor axupimgs print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern help emoticons autosave autoresize',
            toolbar: 'codeeditor undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
                     styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
                     table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs importword kityformula-editor',
            fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
            font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
            autosave_ask_before_unload: false,
            toolbar_mode: 'wrap',
            images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => {
                var xhr, formData;
                var file = blobInfo.blob();//转化为易于理解的file对象
                xhr = new XMLHttpRequest();
                xhr.withCredentials = false;
                xhr.open('POST', window.globalConfig.url_file);
                xhr.onload = function () {
                    var json;
                    if (xhr.status != 200) {
                        reject('HTTP Error: ' + xhr.status);
                        return;
                    }
                    json = JSON.parse(xhr.responseText);
                    if (!json || json.code !== 0) {
                        reject(json.msg);
                        return;
                    }
                    let basePath = window.globalConfig.img_bind_url;

                    let imgPath = `${basePath}${json.data.local_url}${json.data.files[0]}`
                    resolve(imgPath);
                };
                formData = new FormData();
                formData.append('files[]', file, file.name);//此处与源文档不一样
                xhr.send(formData);
            }),
            branding: false, // 文档里的图片路由更换
            relative_urls: false,
            remove_script_host: true,
            document_base_url: `${window.globalConfig.base_domain}`, //标签管理
            // valid_children: "+a[div|h4|p|id],+span[div],+select[id|onchange],+button[class|type],+div[h1]",
            // extended_valid_elements: "span[class|style],a[href|target|class|id],button[class|type],select[id|onchange],i",
            valid_children: "*[*]",
            valid_elements: "*[*]",
            extended_valid_elements: "*[*]",
            max_height: 700,
            min_height: 700,
            license_key: 'gpl',
            promotion: false,
            image_dimensions: false,
            codeeditor_wrap_mode: true,
            codeeditor_font_size: 14,
            codeeditor_themes_pack: ["twilight", "merbivore", "dawn", "kuroir"]
        });
    }

    /**
     * 统一上传的插件
     * @param elem_id class="layui-upload-list"的同级id
     * @param photo_img_id img标签的id
     * @param hidden_img_id 隐藏文本的id
     * @returns {*}
     */
    var uploader = (elem_id, photo_img_id, hidden_img_id) => {
        var loadIndex = undefined
        return upload.render({
            elem: `#${elem_id}`//'#ID-upload-mobile-ico-btn'
            , url: window.globalConfig.url_file, field: "files[]", data: {
                save_type: 1
            }, before: function (obj) {
                //预读本地文件示例，不支持ie8
                obj.preview(function (index, file, result) {
                    // $('#ID-upload-photo-img').attr('src', result); //图片链接（base64）
                    $(`#${photo_img_id}`).attr('src', result); //图片链接（base64）
                });
                loadIndex = layer.msg('上传中', {
                    icon: 16, shade: 0.01
                });
            }, done: function (res) {
                layer.close(loadIndex)
                // $("#photo").val(res.data.local_url + res.data.files[0])
                $(`#${hidden_img_id}`).val(res.data.local_url + res.data.files[0])
                //上传完毕
                ctmMsg(res.code, res.msg)
            }
        });
    }


    /**
     * 表格列表文本修改方法
     * @param tableElem 表格对象
     * @param requestUri 请求地址
     * @param idName id的名称 应对 cms_id  article_id这种
     */
    var tableTextEditor = (tableElem, requestUri, idName = 'id') => {
        table.on(`edit(${tableElem})`, function (obj) {
            var value = obj.value // 得到修改后的值
            var data = obj.data // 得到所在行所有键值
            var id = data[idName]
            var field = obj.field; // 得到字段
            let postData = {}
            postData[field] = value;
            var loadIndex = layer.msg('操作中', {
                icon: 16, shade: 0.01
            });
            admin.req({
                url: requestUri + "/" + id, type: "PUT", data: postData, success: function (res) {
                    layer.close(loadIndex)
                    ctmMsg(res.code, res.msg)

                    if (field.indexOf('order') !== -1 || field.indexOf('sort') !== -1) {
                        table.reloadData(tableElem)
                    }

                }
            })
        });
    }

    /**
     * 表格checkbox切换修改方法
     * @param switchElem checkbox元素
     * @param requestUri 请求地址
     */
    var tableSwitchEditor = (switchElem, requestUri) => {
        form.on(`switch(${switchElem})`, function (obj) {
            var name = this.name;
            var id = this.value
            let postData = {}
            postData[name] = obj.elem.checked ? 1 : 0;
            var loadIndex = layer.msg('操作中', {
                icon: 16, shade: 0.01
            });
            admin.req({
                url: requestUri + "/" + id, type: "PUT", data: postData, success: function (res) {
                    layer.close(loadIndex)
                    ctmMsg(res.code, res.msg)
                }
            })
        });
    }

    /**
     * 自定消息提示
     * @param code
     * @param msg
     */
    var ctmMsg = (code, msg) => {
        let status = code === 0;
        let $icon = status ? 1 : 0;
        layer.msg(msg, {
            icon: $icon, offset: "rt", skin: "layui-layer-lan", anim: 'slideDown'
        }, function () {
            // layer.msg('提示框关闭后的回调');
        });
    }

    /**
     * 表单下拉框 渲染
     * 下拉列表的 class 一定是 .dropdown-demo
     * @param options table本体(this)
     * @param listUri 下来列表的Uri
     * @param editUrl 需要修改的Uri
     * @param idName 需要修改的主体的id名称
     * @param postDataName 要修改的数据名称
     * @param replaceName 要替换的name值 默认为name
     * @param replaceId 要替换的id值 默认为id
     * ```
     *  这里面的name
     *  data = JSON.parse(JSON.stringify(data).replace(/name/g, 'title'))
     * ```
     */
    var tableDropdownEditor = (options, listUri, editUrl, idName, postDataName, replaceName = 'name', replaceId = undefined) => {
        var dropdown = layui.dropdown
        var getRowData = function (tableId, elem) {
            var index = $(elem).closest('tr').data('index');
            return table.cache[tableId][index] || {};
        };
        admin.req({
            url: listUri, type: 'get', dataType: 'json', success: function (response) {
                var data = response.data;
                data = JSON.parse(JSON.stringify(data).replace(new RegExp(replaceName, 'g'), 'title').replace(/children/g, 'child'))
                if (replaceId) {
                    data = JSON.parse(JSON.stringify(data).replace(new RegExp(replaceId, 'g'), 'id'))
                }

                dropdown.render({
                    clickScope: 'all', elem: '.dropdown-demo', data: data, click: function (obj) {
                        var data = getRowData(options.id, this.elem); // 获取当前行数据(如 id 等字段，以作为数据修改的索引)
                        this.elem.find('span').html(obj['title']);
                        // 更新数据中对应的字段
                        // data.sex = obj.title;
                        let postData = {}
                        postData[postDataName] = obj['id'];
                        admin.req({
                            url: editUrl + "/" + data[idName], type: 'PUT', data: postData, success: function (res) {
                                ctmMsg(res.code, res.msg)
                            }
                        })
                    }
                });
            }
        });
    }


    /**
     * 弹窗 添加/更新
     * @param title 标题
     * @param baseUrl 请求地址
     * @param tableElem 列表elem
     * @param formUrl 表单路径
     * @param formElem 表单elem
     * @param formSubmitElem 表单提交elem
     * @param data 页面数据
     * @param sizes 弹窗的大小
     */
    var popupSaveHandler = (title, baseUrl, tableElem, formUrl, formElem, formSubmitElem, data = {}, sizes = ['350px', '550px']) => {
        var admin = layui.admin, view = layui.view, form = layui.form
        admin.popup({
            title: title, area: ['350px', '550px'], id: 'LAY-popup-content-add', success: function (layero, index) {
                view(this.id).render(formUrl, data).done(function () {
                    form.render(null, `${formElem}`);

                    //提交
                    form.on(`submit(${formSubmitElem})`, function (data) {
                        var field = data.field; //获取提交的字段
                        let type = 'POST'
                        let requestUri = baseUrl
                        if (field.id) {
                            type = "PUT"
                            requestUri += "/" + field.id
                        }

                        var loadIndex = layer.msg('操作中', {
                            icon: 16, shade: 0.01
                        });
                        //提交 Ajax 成功后，关闭当前弹层并重载表格
                        admin.req({
                            url: requestUri, type: type, data: field, success: function (res) {
                                ctmMsg(res.code, res.msg)
                                layer.close(index)
                                layer.close(loadIndex)
                                layui.table.reloadData(`${tableElem}`); //重载表格
                            }
                        })
                    });
                });
            }
        });
    }

    /**
     * 上传附件
     * @param elem_id
     * @param file_dom_id
     * @returns {*}
     */
    var uploaderFile = (elem_id, file_dom_id) => {
        var loadIndex = undefined
        return upload.render({
            elem: `#${elem_id}`//'#ID-upload-mobile-ico-btn'
            , url: window.globalConfig.url_file, accept: 'file', field: "files[]", before() {
                loadIndex = layer.msg('上传中', {
                    icon: 16, shade: 0.01
                });
            }, done: function (res) {
                layer.close(loadIndex)
                // $("#photo").val(res.data.local_url + res.data.files[0])
                $(`#${file_dom_id}`).val(res.data.local_url + res.data.files[0])
                //上传完毕
                ctmMsg(res.code, res.msg)

            }
        });
    }

    let access_token = layui.data(setter.tableName).access_token
    if (access_token) {
        // 请求后台oss是否开关
        admin.req({
            url: window.globalConfig.url_config + "/0", data: {
                code: "oss"
            }, success: function (res) {
                $oss = res.data;
                window.globalConfig.img_bind_url = $oss['IS_ENABLED'] === '1' ? $oss['BIND_DOMAIN'] : window.globalConfig.base_domain
            }
        })
    }

    /**
     * 表单下拉列表
     * @param requestUrl 请求地址
     * @param ddElem 下拉列表的id
     * @param idName 表单中的下拉列表的id 名称
     * @param labelName 表单中下拉列表的 名称
     * @param valueId 表单中的下拉列表的值id 名称 默认是id
     * @param valueName 表单中下拉列表的值名称 默认是title
     * ```
     *  <!-- 举个栗子 -->
     *  <script type="text/html" template>
     <input type="text" id="navName" value="{{ d.params.navName }}" class="layui-input" readonly/>
     <input type="hidden" id="navId" name="nav_id" value="{{ d.params.nav_id }}" class="layui-input"/>
     </script>
     * ```
     */
    var formDropdownEditor = (requestUrl, ddElem, idName, labelName, valueId = 'id', valueName = 'title') => {
        var admin = layui.admin, dropdown = layui.dropdown

        var content = "";

        // 加载下拉框
        admin.req({
            url: requestUrl, type: 'get', dataType: 'json', success: function (response) {
                var data = response.data;

                data = JSON.parse(JSON.stringify(data).replace(new RegExp(valueName, 'g'), 'title').replace(/children/g, 'child'))
                dropdown.render({
                    shade: [0.3, '#000'],
                    clickScope: 'all',
                    elem: `#${ddElem}`,
                    data: data,
                    content: content,
                    click(data, othis) {
                        $(`#${idName}`).val(data[valueId])
                        $(`#${labelName}`).val(data['title'])
                    }
                });
            }
        });
    }

    /**
     * 加载列表中搜索里的下拉列表
     * @param options table本体(this)
     * @param listUri 下来列表的Uri
     * @param editUrl 需要修改的Uri
     * @param idName 需要修改的主体的id名称
     * @param postDataName 要修改的数据名称
     * @param replaceName 要替换的name值 默认为name
     * @param replaceId 要替换的id值 默认为id
     * @param inputId 表单中的隐藏id
     * @param dropdownId 表单中的下来框id
     * ```
     *  这里面的name
     *  data = JSON.parse(JSON.stringify(data).replace(/name/g, 'title')) //replaceName
     *
     * <input type="hidden" id="catId" class="layui-input"> //inputId
     * ```
     */
    var tableSearchDropdown = (options, listUri, replaceName = 'name', replaceId = undefined, inputId = undefined, dropdownId = '') => {
        var dropdown = layui.dropdown
        admin.req({
            url: listUri, type: 'get', dataType: 'json', success: function (response) {
                var data = response.data;
                data = JSON.parse(JSON.stringify(data).replace(new RegExp(replaceName, 'g'), 'title').replace(/children/g, 'child'))
                if (replaceId) {
                    data = JSON.parse(JSON.stringify(data).replace(new RegExp(replaceId, 'g'), 'id'))
                }

                data.unshift({id: undefined, title: "全部"});

                dropdown.render({
                    clickScope: 'all', elem: `#${dropdownId}`, data: data, click: function (obj) {
                        this.elem.find('span').html(obj['title']);
                        $(`#${inputId}`).val(obj['id'])
                    }
                });
            }
        });
    }

    /**
     * 自定义请求
     * @param url
     * @param params
     * @param method
     * @param tableId
     * @param showMsg
     * @returns {Promise<unknown>}
     */
    var ctmRequest = function (url, params = [], method = "GET", tableId = false, showMsg = false) {
        return new Promise((resolve, reject) => {
            admin.req({
                url: url, method: method, data: params, done(d) {
                    if (d.code === 0) {
                        let $resp = {data: d.data};
                        if ('count' in d) {
                            $resp.count = d.count;
                        }
                        resolve($resp)
                        // 是否重载表单数据
                        if (tableId) {
                            layui.table.reloadData(tableId)
                        }
                        // 是否显示提示信息
                        if (showMsg) {
                            ctmMsg(d.code, d.msg);
                        }
                    } else {
                        reject(d.msg)
                    }

                }
            })
        })
    };


    /**
     * 提取富文本的标题
     * @param richText
     * @returns {null|string}
     */
    var extractHeadingContent = (richText) => {
        const div = document.createElement('div');
        div.innerHTML = richText;

        const headings = ['h1', 'h2', 'h3', 'h4'];
        for (const headingTag of headings) {
            const elements = div.getElementsByTagName(headingTag);
            if (elements.length > 0) {
                return elements[0].innerText;
            }
        }

        return null;
    }


    /**
     * 加载穿梭插件
     * @param requestUrl 请求列表的id
     * @param ElemId    控件id 不带#
     * @param replaceId 数据的id名称
     * @param replaceName 数据的name名称
     * @param rightData 右侧数据
     * ```
     *  // 加载文章穿梭框
     let articleIds = [];
     if (remoteData.relationCmsInfo) {
     articleIds = remoteData.relationCmsInfo.map(item => item.article_id)
     }
     common.ctmTransfer(
     window.globalConfig.url_cms_list,
     'ID-transfer-cms-value',
     'article_id',
     'title',
     articleIds
     )
     * ```
     */
    var ctmTransfer = (requestUrl, ElemId, replaceId, replaceName, rightData = []) => {
        var transfer = layui.transfer;
        ctmRequest(requestUrl).then(res => {
            transfer.render({
                elem: `#${ElemId}`,
                id: `${ElemId}`,
                data: res.data,
                title: ['待绑定', '已绑定'],
                value: rightData ? rightData : [],
                parseData: function (res) { // 解析成规定的 data 格式
                    return {
                        "value": res[replaceId], // 数据值
                        "title": res[replaceName], // 数据标题
                    };
                },
                text: {
                    none: '无数据'
                }
            });
        })
    }

    /**
     * 获取穿梭框的选中值
     * @param ElementId
     * @returns {*}
     */
    var getCtmTransferData = (ElementId) => {
        var transfer = layui.transfer;
        return transfer.getData(ElementId).map(item => item.value).join(',')
    }

    /**
     * 自动填充图片描述
     * @param richText 需要修改的富文本
     * @param altContent 图片alt内容
     * @returns {string}
     */
    var fillEmptyAltInRichText = (richText, altContent = window.globalConfig.customerName) => {
        const parser = new DOMParser();
        const doc = parser.parseFromString(richText, 'text/html');
        const images = doc.getElementsByTagName('img');
        for (let i = 0; i < images.length; i++) {
            if (!images[i].alt || images[i].alt.trim() === '') {
                // 可以根据实际情况填充合适的 alt 内容，这里简单用'图片描述'替代
                images[i].alt = altContent;
            }
        }
        return doc.documentElement.innerHTML;
    }

    /**
     * 实例化树图
     * @param url
     * @param elementId
     * @param dataId
     * @param dataName
     * @param checkedData 已勾选的选项
     */
    var ctmTree = (url, elementId, dataId, dataName, checkedData) => {
        var tree = layui.tree;
        ctmRequest(url).then(res => {
            let data = res.data;
            tree.render({
                elem: `#${elementId}`,
                data: data,
                showCheckbox: true,  // 是否显示复选框
                onlyIconControl: true,  // 是否仅允许节点左侧图标控制展开收缩
                id: `${elementId}`,
                isJump: false, // 是否允许点击节点时弹出新窗口跳转
                customName: {
                    'id': dataId,
                    'title': dataName
                }
            });

            if (checkedData) {
                tree.setChecked(elementId, checkedData);
            }
        });
    }

    /**
     * 获取树图的数据
     * @param elementId 组件id
     * @param id 提取的id值
     * @returns {*}
     */
    var getCtmTreeData = (elementId, id) => {
        var tree = layui.tree;

        function extractIds(obj) {
            let ids = [];
            if (obj && obj[id]) {
                ids.push(obj[id]);
            }
            if (obj.children && obj.children.length > 0) {
                obj.children.forEach(child => {
                    ids = ids.concat(extractIds(child));
                });
            }
            return ids;
        }

        let checkedData = tree.getChecked(elementId);
        return checkedData.reduce((acc, item) => acc.concat(extractIds(item)), []).join(',');
    }

    /**
     * 随机生成路由
     * @param length
     * @returns {string}
     */
    var generateRandomRewriteUrl = (length = 10) => {
        const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        for (let i = 0; i < length; i++) {
            const randomIndex = Math.floor(Math.random() * characters.length);
            result += characters.charAt(randomIndex);
        }
        return result;
    }

    /**
     * 加载编辑器
     * @param remoteData 远程数据
     * @param editors
     */
    var loadEditors = (remoteData,editors) => {
        for (const editorsKey in editors) {
            editor(editorsKey);
            tinymce.get(editorsKey).on('init', () => {
                if (remoteData[editors[editorsKey]]) {
                    tinymce.get(editorsKey).setContent(remoteData[editors[editorsKey]])
                }
            })
        }
    }

    /**
     * 获取编辑器的内容
     * @param field 表单提交的field
     * @param editors 编辑器列表
     * @returns {*}
     */
    var getEditorsContent = (field, editors) => {
        for (const editorsKey in editors) {
            field[editors[editorsKey]] = tinymce.get(editorsKey).getContent()
            // if (!field[editors[editorsKey]]) {
            //     delete field[editors[editorsKey]]
            // }
        }
        return field;
    }

    //对外暴露的接口
    exports('common', {
        editor: editor,
        uploader: uploader,
        uploaderFile: uploaderFile,
        tableTextEditor: tableTextEditor,
        tableSwitchEditor: tableSwitchEditor,
        ctmMsg: ctmMsg,
        tableDropdownEditor: tableDropdownEditor,
        popupSaveHandler: popupSaveHandler,
        formDropdownEditor: formDropdownEditor,
        tableSearchDropdown: tableSearchDropdown,
        ctmRequest: ctmRequest,
        extractHeadingContent: extractHeadingContent,
        ctmTransfer: ctmTransfer,
        getCtmTransferData: getCtmTransferData,
        fillEmptyAltInRichText: fillEmptyAltInRichText,
        ctmTree: ctmTree,
        getCtmTreeData: getCtmTreeData,
        generateRandomRewriteUrl: generateRandomRewriteUrl,
        loadEditors: loadEditors,
        getEditorsContent: getEditorsContent,
    });
});
